#include "preHeader.h"
#include "ChatServer.h"
#include "Game/CharacterMgr.h"
#include "Session/MapServerMgr.h"
#include "Session/GateServerMgr.h"
#include "Team/Team.h"

ChatServer::ChatServer()
{
}

ChatServer::~ChatServer()
{
}

void ChatServer::SendPacketToAllPlayer(const INetPacket& pck)
{
	sGateServerMgr.BroadcastPacket2AllClient(pck);
}

void ChatServer::SendSysMsgToAll(ChannelType channelType, uint32 msgFlags,
	uint32 msgId, const std::string_view& msgArgs)
{
	NetPacket pack(SMSG_SYSTEM_MESSAGE);
	pack << (s8)channelType << msgFlags << msgId;
	pack.Append(msgArgs.data(), msgArgs.size());
	SendPacketToAllPlayer(pack);
}

int ChatServer::HandleChatMessage(
	ChannelType channelType, Character* pChar, ObjGUID toGuid,
	const std::string_view& strMsg, const std::string_view& strArgs)
{
	GErrorCode errCode = InvalidRequest;
	switch (channelType) {
	case ChannelType::tWhisper:
		errCode = sChatServer.HandleChatMessage4Whisper(pChar, toGuid, strMsg, strArgs);
		break;
	case ChannelType::tSpeak:
		errCode = sChatServer.HandleChatMessage4Speak(pChar, strMsg, strArgs);
		break;
	case ChannelType::tTeam:
		errCode = sChatServer.HandleChatMessage4Team(pChar, strMsg, strArgs);
		break;
	case ChannelType::tGuild:
		errCode = sChatServer.HandleChatMessage4Guild(pChar, strMsg, strArgs);
		break;
	case ChannelType::tWorld:
		errCode = sChatServer.HandleChatMessage4World(pChar, strMsg, strArgs);
		break;
	}
	if (errCode != CommonSuccess) {
		pChar->SendError(errCode);
	}
	return SessionHandleSuccess;
}

GErrorCode ChatServer::HandleChatMessage4Whisper(Character* pChar, ObjGUID toGuid,
	const std::string_view& strMsg, const std::string_view& strArgs)
{
	if (toGuid == ObjGUID_NULL) {
		return TargetInvalid;
	}

	auto pToChar = toGuid.SID == 0 ? sCharacterMgr.GetCharacter(toGuid) : NULL;
	if (pToChar == NULL) {
		TransClientChatMessage(ChannelType::tWhisper, pChar, toGuid, strMsg, strArgs);
		return CommonSuccess;
	}

	NetPacket pack;
	BuildClientChatMessagePacket(pack, ChannelType::tWhisper, pChar, strMsg, strArgs);
	pToChar->SendPacket(pack);

	return CommonSuccess;
}

GErrorCode ChatServer::HandleChatMessage4Speak(Character* pChar,
	const std::string_view& strMsg, const std::string_view& strArgs)
{
	TransClientChatMessage(ChannelType::tSpeak, pChar, ObjGUID_NULL, strMsg, strArgs);
	return CommonSuccess;
}

GErrorCode ChatServer::HandleChatMessage4Team(Character* pChar,
	const std::string_view& strMsg, const std::string_view& strArgs)
{
	if (pChar->pTeam == NULL) {
		return ErrNotInTeam;
	}

	NetPacket pack;
	BuildClientChatMessagePacket(pack, ChannelType::tTeam, pChar, strMsg, strArgs);
	pChar->pTeam->SendPacketToAllMembers(pack);

	return CommonSuccess;
}

GErrorCode ChatServer::HandleChatMessage4Guild(Character* pChar,
	const std::string_view& strMsg, const std::string_view& strArgs)
{
	return CommonSuccess;
}

GErrorCode ChatServer::HandleChatMessage4World(Character* pChar,
	const std::string_view& strMsg, const std::string_view& strArgs)
{
	NetPacket pack;
	BuildClientChatMessagePacket(pack, ChannelType::tWorld, pChar, strMsg, strArgs);
	SendPacketToAllPlayer(pack);
	return CommonSuccess;
}

void ChatServer::TransClientChatMessage(
	ChannelType channelType, Character* pChar, ObjGUID toGuid,
	const std::string_view& strMsg, const std::string_view& strArgs)
{
	NetPacket pack(CMSG_CHAT_MESSAGE);
	pack << (s8)channelType << toGuid << strMsg;
	pack.Append(strArgs.data(), strArgs.size());
	sMapServerMgr.RouteToPlayer(pChar, pack);
}

void ChatServer::BuildClientChatMessagePacket(
	INetPacket& pck, ChannelType channelType, Character* pChar,
	const std::string_view& strMsg, const std::string_view& strArgs)
{
	pck.Reset(SMSG_CHAT_MESSAGE);
	pck << (s8)channelType << pChar->guid << pChar->name << strMsg;
	pck.Append(strArgs.data(), strArgs.size());
}
